﻿//IMessageWrapper.cs
//Copyright (c) 2013 StockSharp LLC, all rights reserved.
//This code module is part of StockSharp library.
//This code is licensed under the GNU GENERAL PUBLIC LICENSE Version 3.
//See the file License.txt for the license details.
//More info on: http://stocksharp.com

namespace StockSharp.Plaza.Wrappers
{
	using System;

	/// <summary>
	/// Основной интерфейс объекта, который используется приложением для обработки полей бизнес-сообщения и отправки сообщений.
	/// </summary>
	interface IMessageWrapper
	{
		/// <summary>
		/// Адрес получателя.
		/// </summary>
		string DestAddr { get; set; }

		/// <summary>
		/// Задать значение поля.
		/// </summary>
		/// <param name="name">Имя поля.</param>
		/// <param name="pVal">Значение.</param>
		void SetField(string name, object pVal);

		/// <summary>
		/// Получить значение поля.
		/// </summary>
		/// <param name="name">Имя поля.</param>
		/// <returns></returns>
		object GetField(string name);

		/// <summary>
		/// Асинхронная отправка сообщений.
		/// </summary>
		/// <param name="conn">Интерфейс соединения.</param>
		/// <param name="timeout">Таймаут в миллисекундах, в течение которого ожидается ответное сообщение.</param>
		/// <param name="dispatcher">Интерфейс обратного вызова.</param>
		/// <param name="eventParam">Дополнительный параметр.</param>
		void SendAsync(IConnectionWrapper conn, long timeout, MessageDispatcher dispatcher, long eventParam);

		/// <summary>
		/// Отправка сообщений.
		/// </summary>
		/// <param name="conn">Интерфейс соединения.</param>
		/// <param name="timeout">Таймаут в миллисекундах, в течение которого ожидается ответное сообщение.</param>
		/// <returns></returns>
		IMessageWrapper Send(IConnectionWrapper conn, long timeout);
	}

	class MessageWrapper32 : IMessageWrapper
	{
		private readonly P2ClientGateMTA32.CP2BLMessage _message;

		public MessageWrapper32(P2ClientGateMTA32.CP2BLMessage message)
		{
			_message = message;
		}

		string IMessageWrapper.DestAddr
		{
			get { return _message.DestAddr; }
			set { _message.DestAddr = value; }
		}

		void IMessageWrapper.SetField(string name, object pVal)
		{
			_message.Field[name] = pVal;
		}

		object IMessageWrapper.GetField(string name)
		{
			return _message.Field[name];
		}

		void IMessageWrapper.SendAsync(IConnectionWrapper conn, long timeout, MessageDispatcher dispatcher, long eventParam)
		{
			var connect = (ConnectionWrapper32)conn;

			if (timeout < 0)
				throw new ArgumentException(@"Значение параметра не может быть отрицательным.", "timeout");

			_message.SendAsync2(connect.Connection, (uint)timeout, dispatcher, eventParam);
		}

		IMessageWrapper IMessageWrapper.Send(IConnectionWrapper conn, long timeout)
		{
			var connect = (ConnectionWrapper32)conn;

			if (timeout < 0)
				throw new ArgumentException(@"Значение параметра не может быть отрицательным.", "timeout");

			return new MessageWrapper32(_message.Send(connect.Connection, (uint)timeout));
		}
	}

	class MessageWrapper64 : IMessageWrapper
	{
		private readonly P2ClientGateMTA64.CP2BLMessage _message;

		public MessageWrapper64(P2ClientGateMTA64.CP2BLMessage message)
		{
			_message = message;
		}

		string IMessageWrapper.DestAddr
		{
			get { return _message.DestAddr; }
			set { _message.DestAddr = value; }
		}

		void IMessageWrapper.SetField(string name, object pVal)
		{
			_message.Field[name] = pVal;
		}

		object IMessageWrapper.GetField(string name)
		{
			return _message.Field[name];
		}

		void IMessageWrapper.SendAsync(IConnectionWrapper conn, long timeout, MessageDispatcher dispatcher, long eventParam)
		{
			var connect = (ConnectionWrapper64)conn;

			if (timeout < 0)
				throw new ArgumentException(@"Значение параметра не может быть отрицательным.", "timeout");

			_message.SendAsync2(connect.Connection, (uint)timeout, dispatcher, eventParam);
		}

		IMessageWrapper IMessageWrapper.Send(IConnectionWrapper conn, long timeout)
		{
			var connect = (ConnectionWrapper64)conn;

			if (timeout < 0)
				throw new ArgumentException(@"Значение параметра не может быть отрицательным.", "timeout");

			return new MessageWrapper64(_message.Send(connect.Connection, (uint)timeout));
		}
	}
}